<template>
	<echartBox title="客户统计" width="656px" height="550px">
		<div class="echart-show" ref="chart"></div>
	</echartBox>
</template>

<script>
import * as echarts from "echarts";
import "echarts-gl";
import echartBox from "../echart-box.vue";

export default {
	name: "padPage1ItemBox3",
	components: {
		echartBox,
	},
	props: {
		chartData: {
			type: Array,
			required: true,
			default: () => []
		}
	},
	methods: {
		// 初始化图表的统一方法名
		initChart() {
			this.buildCustomerChart();
		},
		// 构建客户统计3D饼图
		buildCustomerChart() {
			const dataList = this.chartData.map((item) => ({
				name: item.name,
				val: item.value,
				itemStyle: {
					color: item.color || 'rgba(0, 81, 180, 0.5)',
				},
			}));
			
			let chartContainer = this.$refs.chart;
			let myChart = echarts.init(chartContainer);
			const heightProportion = 0.2;

			// 生成扇形的曲面参数方程
			function getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, height) {
				let midRatio = (startRatio + endRatio) / 3;
				let startRadian = startRatio * Math.PI * 2;
				let endRadian = endRatio * Math.PI * 2;
				let midRadian = midRatio * Math.PI * 2;

				if (startRatio === 0 && endRatio === 1) {
					isSelected = false;
				}

				k = typeof k !== 'undefined' ? k : 1 / 3;
				let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
				let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
				let hoverRate = isHovered ? 1.1 : 1;

				return {
					u: {
						min: -Math.PI,
						max: Math.PI * 3,
						step: Math.PI / 32
					},
					v: {
						min: 0,
						max: Math.PI * 2,
						step: Math.PI / 20
					},
					x: function (u, v) {
						if (u < startRadian) {
							return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
						}
						if (u > endRadian) {
							return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
						}
						return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
					},
					y: function (u, v) {
						if (u < startRadian) {
							return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
						}
						if (u > endRadian) {
							return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
						}
						return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
					},
					z: function (u, v) {
						if (u < -Math.PI * 0.5) {
							return Math.sin(u);
						}
						if (u > Math.PI * 2.5) {
							return Math.sin(u);
						}
						return Math.sin(v) > 0 ? heightProportion * height : -1;
					}
				};
			}

			// 生成模拟 3D 饼图的配置项
			function getPie3D(pieData, internalDiameterRatio) {
				let series = [];
				let sumValue = 0;
				let startValue = 0;
				let endValue = 0;
				let legendData = [];
				let linesSeries = [];
				let k = typeof internalDiameterRatio !== 'undefined' ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio) : 1 / 3;

				for (let i = 0; i < pieData.length; i++) {
					sumValue += pieData[i].value;
					let seriesItem = {
						name: typeof pieData[i].name === 'undefined' ? `series${i}` : pieData[i].name,
						type: 'surface',
						parametric: true,
						wireframe: {
							show: false
						},
						pieData: pieData[i],
						pieStatus: {
							selected: false,
							hovered: false,
							k: k
						}
					};

					if (typeof pieData[i].itemStyle != 'undefined') {
						let itemStyle = {};
						typeof pieData[i].itemStyle.color != 'undefined' ? itemStyle.color = pieData[i].itemStyle.color : null;
						typeof pieData[i].itemStyle.opacity != 'undefined' ? itemStyle.opacity = pieData[i].itemStyle.opacity : null;
						seriesItem.itemStyle = itemStyle;
					}
					series.push(seriesItem);
				}

				for (let i = 0; i < series.length; i++) {
					endValue = startValue + series[i].pieData.value;
					series[i].pieData.startRatio = startValue / sumValue;
					series[i].pieData.endRatio = endValue / sumValue;
					series[i].parametricEquation = getParametricEquation(
						series[i].pieData.startRatio,
						series[i].pieData.endRatio,
						false,
						false,
						k,
						series[i].pieData.value
					);

					startValue = endValue;

					let midRadian = (series[i].pieData.endRatio + series[i].pieData.startRatio) * Math.PI;
					let posX = Math.cos(midRadian) * (1 + Math.cos(Math.PI / 2));
					let posY = Math.sin(midRadian) * (1 + Math.cos(Math.PI / 2));
					let posZ = Math.log(Math.abs(series[i].pieData.value + 1)) * 0.1;
					let flag = ((midRadian >= 0 && midRadian <= Math.PI / 2) || (midRadian >= 3 * Math.PI / 2 && midRadian <= Math.PI * 2)) ? 1 : -1;
					let color = pieData[i].itemStyle.color;
					let turningPosArr = [posX * (1.8) + (i * 0.1 * flag) + (flag < 0 ? -0.5 : 0), posY * (1.8) + (i * 0.1 * flag) + (flag < 0 ? -0.5 : 0), posZ * (2)]
					let endPosArr = [posX * (1.9) + (i * 0.1 * flag) + (flag < 0 ? -0.5 : 0), posY * (1.9) + (i * 0.1 * flag) + (flag < 0 ? -0.5 : 0), posZ * (6)]

					linesSeries.push({
						type: 'line3D',
						lineStyle: {
							color: color,
						},
						data: [[posX, posY, posZ], turningPosArr, endPosArr]
					},
					{
						type: 'scatter3D',
						label: {
							show: true,
							distance: 0,
							position: 'center',
							textStyle: {
								color: '#ffffff',
								backgroundColor: color,
								borderWidth: 2,
								fontSize: 14,
								padding: 10,
								borderRadius: 4,
							},
							formatter: '{b}'
						},
						symbolSize: 0,
						data: [{ name: series[i].name + '\n' + series[i].pieData.val, value: endPosArr }]
					});

					legendData.push(series[i].name);
				}
				series = series.concat(linesSeries)

				// 最底下圆盘
				series.push({
					name: 'mouseoutSeries',
					type: 'surface',
					parametric: true,
					wireframe: {
						show: false,
					},
					itemStyle: {
						opacity: 1,
						color: 'rgba(25, 93, 176, 1)',
					},
					parametricEquation: {
						u: {
							min: 0,
							max: Math.PI * 2,
							step: Math.PI / 20,
						},
						v: {
							min: 0,
							max: Math.PI,
							step: Math.PI / 20,
						},
						x: function (u, v) {
							return ((Math.sin(v) * Math.sin(u) + Math.sin(u)) / Math.PI) * 2;
						},
						y: function (u, v) {
							return ((Math.sin(v) * Math.cos(u) + Math.cos(u)) / Math.PI) * 2;
						},
						z: function (u, v) {
							return Math.cos(v) > 0 ? -0 : -1.5;
						},
					},
				});
				return series;
			}

			let total = 0
			dataList.forEach(item => {
				total += item.val
			})
			
			const series = getPie3D(dataList.map(item => {
				item.value = Number((item.val / total * 100).toFixed(2))
				return item
			}), 0.8, 240, 28, 26, 1);

			const option = {
				legend: {
                    show: false,
					tooltip: {
						show: false,
					},
					data: dataList.map(item => item.name),
					top: '5%',
					left: '5%',
					icon: 'circle',
					textStyle: {
						color: '#fff',
						fontSize: 14,
					},
				},
				animation: true,
				labelLine: {
					show: true,
					lineStyle: {
						color: '#7BC0CB',
					},
				},
				label: {
					show: false,
				},
				xAxis3D: {
					min: -1,
					max: 1,
				},
				yAxis3D: {
					min: -1,
					max: 1,
				},
				zAxis3D: {
					min: -1,
					max: 1,
				},
				grid3D: {
					show: false,
					boxHeight: 4,
					bottom: '40%',
					viewControl: {
						distance: 160,
						alpha: 25,
						beta: 60,
						autoRotate: true,
						rotateSensitivity: 0,
						zoomSensitivity: 0,
						panSensitivity: 0,
						enableZoom: false,
						enablePan: false,
						enableRotate: false,
					},
				},
				series: series,
			};

			myChart.setOption(option);
			
			// 强制禁用所有交互
			myChart.getZr().off('mousewheel');
			myChart.getZr().off('wheel');
			myChart.getZr().off('pan');
			myChart.getZr().off('drag');
		}
	},
};
</script>

<style scoped lang="scss">
.echart-show {
	width: 100%;
	height: 100%;
    transform: translateY(40px);
    pointer-events: none; /* 禁用所有鼠标事件 */
}
</style>